Back to IRIX

Pipeline, January/February 1996, vol.7, no.1
Copyright © 1996 Silicon Graphics


Automating and Scheduling Jobs with Cron


Many jobs that users and system administrators need to accomplish are
repetitive or are best done during off hours when the system load is lighter.

This article will discuss how to use cron(1M) to schedule and manage these jobs. Although the information in this article should apply equally to IRIX 5.x and IRIX 6.x, it was researched and tested on IRIX 5.3.

The Cron Daemon

Cron is the IRIX clock daemon which executes commands at a specified date and time. There are three ways to schedule a task using cron; at(1), batch(1), and crontab(1).

Typically, if a task only needs to be done once, the at or batch commands are used. If a task needs to be regularly scheduled, then the crontab command is used.

While the at command allows the user to specify the date and time that the task should be executed, the batch command does not. Batch jobs are placed in a queue and are executed when the system load level permits. In this case, the system decides when it is appropriate to start a task, and not the user. Because this is typically not what a user wants, the batch command is seldom used and will not be covered in this article.

Scheduling Jobs with At

The time an at job should run can be specified using one, two, or four digits. One and two digit numbers specify hours, while four digit numbers indicate hours and minutes. If desired, a colon can be inserted between the hours and minutes for readability. The suffix am or pm may be specified. If no suffix is specified, a 24-hour clock is used. At also understands some special names such as noon and midnight. In general, users should avoid scheduling jobs between 1AM and 2AM because of problems that may occur when daylight savings time stops or starts.

Dates can be specified using a month name followed by a number indicating the day. Alternately, the day of the week can be specified, or special names such as today and tomorrow can be used. If the date is not specified, today is assumed if the given hour is greater than the current hour, and tomorrow is assumed if it is less.

For example, if the current date is Tue Oct 31 14:42:20 PST 1995, and the at job is to start at Wed Nov 1 12:00:00 PST 1995, then the following commands are equivalent:

% at 12pm tomorrow 
% at noon Wed 
% at 1200 Nov 1
For more information on scheduling at jobs, refer to the manual page for at(1). For examples illustrating how to use at, refer to the section titled "Examples" later in this article.

Scheduling Jobs with Crontab

When a task needs to be regularly scheduled, the crontab command is typically employed. The crontab command copies the specified cron table file (or standard input) into a directory that holds all user cron tables. The file that is passed to crontab is called a crontab file and contains both the date and time the job should run, as well as the job itself.

The format of a crontab file is:

minute	hour	daymonth	month	dayweek	command
The first five fields are specified in the following manner:
o	minute (0 through 59) 
o	hour (0 through 23) 
o	day of the month (1 through 31) 
o	month of the year (1 through 12) 
o	day of the week (0 through 6, where 0 is equal to 
	Sunday)
Each of these fields may be either an asterisk (meaning all legal values), or a list of elements separated by commas. An element is either one number or two numbers separated by a minus sign (defining an inclusive range). Each field must be separated by either a tab, or one or more spaces. As stated in the previous section, scheduling jobs between 1AM and 2AM should be discouraged because of problems that may occur when daylight savings time stops or starts.

The command field is the command to be executed. This can be a single command, a sequence of commands, or a shell script. Note that a very limited Bourne shell environment is provided for commands run via crontab. Refer to the section titled "The Shell Environment" later in this article for more information.

For example, the following crontab entry would run the df(1) command at midnight on the 15th day of each month.

# minute	hour	daymonth	month	dayweek	command

0		0	15		*	*	df
For more information on specifying when a crontab job should run, refer to the manual page for crontab(1). For examples illustrating how to use crontab, refer to the next section.

Examples

This section provides several examples of how a user or system administrator might use cron to manage various jobs. The examples include:

o	printing a large job during non-peak hours 
o	using the calendar(1) reminder service 
o	automatically updating systems with rdist(1C)
Scheduling Printing Jobs

In most cases, printers are a shared resource among many users. Printing large documents during the day can often be a problem. One way of solving this problem is to use the at command to print the document after normal working hours. For example, to print a document called mydoc starting at 8PM today on the default printer, use the following command:

% at 8pm lp /usr/people/adze/mydoc

 <ctrl-d> 		(hold down the ctrl key and press d)
IRIX will respond with something similar to the following:
warning: commands will be executed using /bin/sh 
job 815180160.a at Tue Oct 31 20:00:00 1995
The warning is printed if the login shell of the user (as defined in the file /etc/passwd) is something other than the Bourne shell. It serves to warn the user that the Bourne shell is used to execute the commands. If the commands require another shell, they will not work. Note that the number after the word job (in this case 815180160) is the job number of this task.

By default, when cron runs an at job, an e-mail message is mailed to the invoking user containing the standard output and standard error of the command, if any was produced. Continuing the example above, the user should expect to see a mail message similar to the following. If an error occurred, examining the error message and comparing it to the file /etc/cron.d/log may help to determine the problem. Refer to the section titled "Troubleshooting" later in this article for more information.

From adze Tue Oct 31 15:02:03 1995 
Date: Tue, 31 Oct 95 20:00:00 -0800 
From: adze (Adze Ames) 
To: adze 
Subject: cron output

request id is printerA-1745 (1 file)
 ************************************************* 

Cron: The previous message is the standard output
	 and standard error of one of your cron commands.
Using Calendar

Calendar is a reminder service that is provided with IRIX. Calendar reads the file calendar in the current directory and prints out any lines that contain todays or tomorrows date anywhere in the line. Month-day combinations such as Oct 30, October 30, 10/30 are recognized, but not day-month combinations such as 30 October. On weekends, the concept of tomorrow extends through Monday.

To set up the calendar reminder service, use a system editor such as vi(1) to create a file called calendar in each user's home directory. For example, the file /usr/people/adze/calendar could contain the following entries:

10/31 1PM meeting with John Jones, room 12-34 
11/7 8PM Birthday party for Jim, bring cookies
1/11 2PM Dentist appointment
Make sure that the permissions on the file /usr/people/adze/calendar are readable by everyone:
% chown adze.user /usr/people/adze/calendar 
% chmod 644 /usr/people/adze/calendar
Each user who wishes to use the calendar reminder service can turn it on individually, or the system administrator can turn it on for all users who have a readable calendar file in their home directories.

Calendar Services For One

For an individual to turn calendar services on, use a system editor such as vi to create a crontab file to submit to cron. In this example, the file is called /usr/people/adze/my.crontab.file, and contains the following:

15 3 * * * if test -x /bin/calendar; \
	then /bin/calendar; fi
This crontab command specifies that at 3:15AM every day, the program calendar will be run for this user only. Note that the command must be on one line.

To submit this job, enter the following command:

% crontab /usr/people/adze/my.crontab.file
The system will respond with the following warning:
warning: commands will be executed using /bin/sh
To make sure that cron recognizes and accepts the crontab job, execute the following command:
% crontab -l

15 3 * * * if test -x /bin/calendar; then /bin/calendar; fi
Note that each user can have one and only one crontab file. However, each crontab file can have multiple commands, with each crontab command requiring one line.

If an error is made, the crontab file can be removed from the crontab directory using the command:

% crontab -r
After the error is corrected, the crontab file can be resubmitted to cron.

When the crontab job runs, the output that cron mails the user will be similar to the following:

From adze Tue Nov 7 03:15:03 1995 
Date: Tue, 7 Nov 95 03:15:03 -0800 
From: adze (Adze Ames) 
To: adze Subject: cron output

11/7 8PM Birthday party for Jim, bring cookies
 ************************************************* 

Cron: The previous message is the standard output
	 and standard error of one of your cron commands.
Calendar Services For All

To enable calendar service for all users on a system that have calendar files in their home directories, the system administrator should complete the following steps.

If the system uses automount(1M) to mount the home directories of non-local users, care must be taken so that all user home directories are not mounted at the same time. This can cause a "mount storm" which can severely impact system performance. System administrators that are considering providing calendar service for all their users should refer to the NFS Administrator's Guide or the ONC3/NFS Administrator's Guide, available on-line with InSight(1), or to the article titled "Using Automount" in the September/October 1995 issue of Pipeline (Volume 6, number 5).

  1. Capture the existing crontab file for root.
    	# crontab -l > /usr/tmp/new.root
    
  2. Using a system editor such as vi, edit the crontab file and add the following two lines to the end of the file (note the argument (-) to the calendar command):
    	# Added calendar service. <date> <name> 
    
    	15 3 * * * if test -x /bin/calendar; \
    		then /bin/calendar - ; fi
    
  3. Submit the new crontab file to cron:
    	# crontab /usr/tmp/new.root
    
  4. Check to make sure that the new crontab job has been accepted by cron:
    	# crontab -l
    
This should list the contents of the old root crontab file, plus the two lines just added.

Updating Systems With Rdist

Rdist is a program to maintain identical copies of files over multiple hosts. It preserves the owner, group, mode, and modification time of files if possible, and can update programs that are executing. Rdist can be used to maintain identical copies of files on a system at work and a home system used for telecommuting, or it can be used to update a client data server from a master server.

Network load, system availability, and the quantity and the size of the updates will determine if it is more appropriate to run rdist during or after normal working hours.

In many cases, a home system used for telecommuting is not left running unless it is actually in use. Because of this, it may be more appropriate to use the at command to schedule rdist updates that coincide with the users lunch or dinner schedule for a particular day.

For example, if a user working from home on a particular day knows that they will be going to lunch at 12:30, the following at command can be used to schedule an rdist update at that time:

% at 12:30 

rsh adze@work "rdist -F -c /usr/people/adze \
	adze@home" 

<ctrl-d>
Note that if the user has a password on their account on either the home or work system, a .rhosts file or a hosts.equiv file must be configured. Refer to the manual page for hosts.equiv(4) for information on configuring these files. One way to be sure that the .rhosts or hosts.equiv files are configured correctly is to make sure that the following commands correctly display the date.
home% rsh adze@work date 
work% rsh adze@home date
home% rsh adze@work "rsh adze@home date"
In the case of updating a client data server from a master data server, a regularly scheduled update using the crontab command is more appropriate. The following crontab command can be used to update a client data server from a master data server Monday through Friday at 11PM. Note that the -oremove option will remove any files in the directory /usr/local/projA on the client system that do not also exist in the directory /usr/local/projA on the master data server.
0 23 * * 1-5 rdist -F -oremove -c\
	 /usr/local/projA \
	<username>@client:/usr/local/projA
As mentioned in the previous example, if the remote account for <username> has a password, a .rhosts file or a hosts.equiv file must be configured.

Before configuring a job to be run by crontab, especially one that is potentially destructive, it is strongly recommended that users and system administrators test the commands by hand, using the Bourne shell, to make sure that the outcome is the desired one.

Note that rdist on IRIX 5.3 and IRIX 6.1 is a newer version than that available on IRIX 5.2 and IRIX 6.0.x. The older version of rdist is available as ordist(1C). For more information, refer to the manual pages for rdist(1C) and ordist(1C).

System Administration Issues

By default, IRIX allows any user to run at, batch or crontab jobs. If desired, the system administrator can prevent users from running cron jobs, or limit the number of jobs running at any one time. This section will provide an overview of how this may be accomplished. Root access is required to modify the configuration.

Preventing Users from Running At Jobs

There are two files that control access to at jobs, /etc/cron.d/at.allow and /etc/cron.d/at.deny, and two files that control access to crontab files, /etc/cron.d/cron.allow and /etc/cron.d/cron.deny. All of these files consist of one user login name per line.

Controlling the Characteristics of Cron Jobs

The file /etc/cron.d/queuedefs controls the characteristics of at and batch jobs as well as the maximum number of at, batch, or crontab jobs that can run at any one time. By default, the contents of this file is:

a.4j1n 
b.2j2n90w
The first character on each line is the name of the queue where a is the queue for at jobs, b is the queue for batch jobs, and c is the queue for crontab jobs. Other queues may be defined by the system administrator.

The characters after the dot define the characteristics of that queue. The string <njob>j is the maximum number of jobs that can run simultaneously in that queue. If more than njob jobs are ready to run, only njob jobs will run. The other jobs will run as the currently running jobs terminate. The default value is 100. This limit is subject to the system wide limit of 25 cron jobs running at any one time.

The string <nice>n is the nice(1) value given to all jobs in that queue that are not run with a user ID of super-user (root). The default value is two.

The string <nwait>w is the number of seconds to wait before rescheduling a job that was deferred because njob jobs were already running in that queue, or because more than 25 total cron jobs were running on the system. The default is 60 seconds.

In the example above, the at queue, queue a, can have at most four jobs running at any one time, and all non-root jobs will be run with a nice value of one. The batch queue, queue b, can have at most two jobs running at any one time, and all non-root jobs will be run with a nice value of two. Attempts to re-run deferred jobs will be scheduled at 90 seconds. Since no queue is defined for crontab jobs, the system defaults are used.

Troubleshooting

This section will briefly describe some of the more common problems encountered when using cron to schedule jobs.

The Cron Daemon

If at or crontab jobs do not appear to be executing, make sure that cron is running:

% ps -eaf | grep cron | grep -v grep 

root	28450	1	0	Oct 30	?	0:07	/etc/cron 
If cron does not appear in the process list, the system administrator can either reboot the system, or they can try stopping and starting cron with the following commands:
# /etc/init.d/cron stop 
# /etc/init.d/cron start
If stopping and starting cron does not work, reboot the system using the command reboot(1M).

The Cron Log File

All actions taken by cron are logged in the file /etc/cron.d/log. Most of the entries recorded here are from the standard IRIX crontab files that manage housekeeping tasks such as removing old core files and rotating sys- tem log files. If problems occur, the log file may be able to help determine what went wrong. Entries in the cron log file are in the following format:

> CMD: if test -x /bin/calendar; then /bin/calendar ; fi 
> adze 3503 { Thu Nov 2 03:15:02 1995 
< adze 3503 { Thu Nov 2 03:15:02 1995
The first line is the crontab command that was submitted to cron, the second line is written when the job is started, and the third line is written when the job completes. Note that in cases where multiple cron jobs are running at the same time, these lines may not be together. Use the process id (3503 in this case) to find the matching start and stop records.

If an at job was submitted to cron, the entries in the log file will be similar to the following:

> CMD: 815180520.a
> adze 572 a Tue Oct 31 15:02:02 1995 
< adze 572 a Tue Oct 31 15:02:02 1995
If the user knows the command submitted with crontab, or they remember the job number returned when submitting the at job, it is possible to search the log file to see if the job was accepted by cron. If the job is not listed, then chances are that there was an error in the at command or crontab file that prevented cron from accepting the job.

Editing Crontab Files

System administrators and users should always use the crontab command to submit jobs to cron. Editing crontab files and then stopping and starting cron may cause unpredictable problems.

The Shell Environment

Many problems with at and crontab jobs can be traced to the shell environment in which they are run. Both at and crontab jobs use the Bourne shell exclusively. Many of the problems that users encounter with cron jobs occur because the commands assume a shell other than the Bourne shell.

When jobs are submitted with at, the shell environment variables, current directory, umask(1), and ulimit are retained. Open file descriptors, traps, and priority are lost.

However, jobs submitted via crontab are supplied a default Bourne shell environment by cron and do not inherit anything from the user's environment. If the user requires a custom environment, the file $HOME/.profile must be explicitly executed in each crontab command in the crontab file; it will not be executed by default.

Users should test their scripts under the Bourne shell to be sure they work before submitting them with the at or crontab commands.

For more information on the default shell environment, refer to the manual pages for at(1) and crontab(1).

Output from Cron Jobs

By default, standard output and standard error are mailed to the user unless they are redirected elsewhere. This is often not what users expect and can cause lost output if sendmail(1M) is not configured properly on the system where the cron job is submitted.

Access Denied

The following error messages will be displayed if a user has been denied the ability to run cron jobs using at or crontab.

% crontab <filename> 
crontab: you are not authorized to use cron. Sorry.

% at 12:59 
at: you are not authorized to use at. Sorry.
This is usually the result of listing the user login name in the files at.deny or cron.deny. Alternately, either the files at.allow and at.deny or cron.deny and cron.allow may be missing.

Syntax Errors

The following message is the result of a syntax error in the crontab file. This is most often caused by a blank line appearing somewhere in the file.

% crontab <filename>
crontab: error on previous line; unexpected character found in line. crontab: the crontab file had syntax errors in it; no change was made.

References

IRIX Admin: System Configuration and Operation,
IRIX Admin: Disks and Filesystems, on-line with InSight(1).

Reference manual pages for at(1), batch(1), cron(1M), crontab(1), rdist(1C), calendar(1), hosts.equiv(4), and nice(1), available on-line.